import { FC, useCallback, useEffect, useRef, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { EmptyVideo, MuteIcon, PauseIcon, PlayIcon, ScreenshotIcon } from '@ycx/ui';
import { useTheme } from '@/store/settingsStore.ts';
import { App, Flex, Space, Tooltip } from 'antd';
import IotServices from '@/api/services/iotServices.ts';
import { useCatch } from '@/hooks';
import Mpegts from 'mpegts.js';
import WebSocketLoader from 'mpegts.js/src/io/websocket-loader';

type Props = {
  carNo?: string;
};

const LiveVideo: FC<Props> = ({ carNo }) => {
  const { message } = App.useApp();
  const theme = useTheme();
  const catchFn = useCatch();
  const [isPlay, setIsPlay] = useState(false);
  const [speed, setSpeed] = useState(0);
  const liveUrl = useRef<string>();

  const videoRef = useRef<HTMLVideoElement>(null);
  const controlWrapperRef = useRef<HTMLElement>(null);

  const { data } = useQuery({
    queryKey: ['equipmentList', carNo],
    queryFn: () => catchFn(() => IotServices.getEquipmentList({ carNo: (carNo as string)! })),
    select: ({ data }) => data,
    enabled: !!carNo,
    staleTime: 0,
  });

  const player = useRef<Mpegts.Player | null>();

  const getWebSocketUrl = (equipmentId: string, channel: string) => {
    return `wss://tc.wvp.uconcern.com:1443/rtp/${equipmentId}_${channel}.live.flv`;
  };

  const getWebSocket = useCallback((): unknown => {
    return class WebSocket extends WebSocketLoader {
      _onWebSocketMessage(e: Record<string, unknown>) {
        if (typeof e.data === 'string') {
          const stateArr = e.data.split('\n\n', 2);
          console.log('stateArr', stateArr);
        } else {
          super._onWebSocketMessage(e);
        }
      }
    };
  }, []);

  const initVideo = () => {
    if (!Mpegts.isSupported()) {
      message.error('Mpegts is not supported');
      return;
    }
    const _player = Mpegts.createPlayer(
      {
        type: 'flv',
        isLive: true,
        hasAudio: false,
        // hasVideo: true,
        cors: true,
        url: liveUrl.current,
      },
      { customLoader: getWebSocket() as Mpegts.CustomLoaderConstructor },
    );

    if (videoRef.current) {
      player.current = _player;
      player.current.attachMediaElement(videoRef.current);
      player.current.load();
      setIsPlay(true);

      player.current?.on(Mpegts.Events.ERROR, () => {
        message.open({
          type: 'info',
          content: '视频播放出错，重新加载中',
          key: 'videoError',
        });
        playerDestroy();
        initVideo();
      });

      player.current?.on(Mpegts.Events.STATISTICS_INFO, (e) => {
        setSpeed(Math.floor(e.speed));
      });
    }
  };

  const playerDestroy = () => {
    if (player.current) {
      console.log('destroyed player');
      player.current?.pause();
      player.current?.unload();
      player.current?.detachMediaElement();
      player.current?.destroy();
      player.current = null;
      setIsPlay(false);
    }
  };

  useEffect(() => {
    if (!data) return;
    const item = data?.[0];
    liveUrl.current = getWebSocketUrl(item.equipmentId, item.channel);
    initVideo();

    return playerDestroy;
  }, [data]);

  useEffect(() => {
    if (!player.current) return;
    if (isPlay) {
      // player.current.load();
      player.current.play();
    } else {
      // player.current.unload();
      player.current.pause();
    }
  }, [isPlay]);

  const handleScreenshot = () => {
    if (!player.current) return;
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    if (!ctx) return;
    canvas.width = videoRef.current?.videoWidth ?? 0;
    canvas.height = videoRef.current?.videoHeight ?? 0;
    ctx.drawImage(videoRef.current as HTMLVideoElement, 0, 0, canvas.width, canvas.height);
    const img = canvas.toDataURL('image/png');
    //save img
    const a = document.createElement('a');
    a.href = img;
    a.download = 'screenshot.png';
    a.click();
  };

  return (
    <>
      {carNo ? (
        <>
          <div
            style={{ height: `calc(100% - ${controlWrapperRef.current?.offsetHeight ?? 54}px)` }}
          >
            <video ref={videoRef} className="h-full w-full object-fill" autoPlay />
          </div>

          <Flex justify="space-between" align="center" className="p-4" ref={controlWrapperRef}>
            <Space size={8}>
              <div
                className="cursor-pointer"
                onClick={() => setIsPlay(!isPlay)}
                style={{ color: 'var(--ycx-font-color-l2)', fontSize: '24px' }}
              >
                <Tooltip title={isPlay ? '暂停' : '播放'} placement="bottom">
                  <div>{isPlay ? <PauseIcon /> : <PlayIcon />}</div>
                </Tooltip>
              </div>
              <Tooltip title="静音" placement="bottom">
                <div>
                  <MuteIcon
                    className="cursor-not-allowed"
                    style={{ color: 'var(--ycx-font-color-l2)', fontSize: '24px' }}
                  />
                </div>
              </Tooltip>
              <Tooltip title="截屏" placement="bottom">
                <div>
                  <ScreenshotIcon
                    className="cursor-pointer"
                    onClick={handleScreenshot}
                    style={{ color: 'var(--ycx-font-color-l2)', fontSize: '24px' }}
                  />
                </div>
              </Tooltip>
            </Space>
            <Flex gap={8}>
              <div>{carNo} </div>
              <div style={{ width: '60px', textAlign: 'right' }}>{speed}kb/s</div>
            </Flex>
          </Flex>
        </>
      ) : (
        <Flex justify="center" align="center" className="h-full">
          <EmptyVideo theme={theme} description={''} />
        </Flex>
      )}
    </>
  );
};

export default LiveVideo;
